
#include "playerAnim.h"
#include "res.h"
/*0down  1up 2right  3left */
typedef struct
{
    int currentFrameIndex;
    uint32_t globalFramesCount;
    SDL_Rect frames[4][5];
    SDL_bool _walking;
    float speed;
    int currentDir;
    SDL_RendererFlip frameFlip;
} WalkAnimationData;

static void WalkAnimationOnDraw(struct DisplayObject *displayObject, SDL_Renderer *renderer)
{
    WalkAnimationData *data = displayObject->subClassData;

    SDL_RenderCopyExF(
        renderer, resGetPlayerText(),
        &data->frames[data->currentDir][data->currentFrameIndex],
        displayObject->dest,
        0, NULL, data->frameFlip);

    data->globalFramesCount++;
    if (data->_walking)
    {
        if (data->globalFramesCount % 10 == 0)
        {
            if (data->currentDir == 2 || data->currentDir == 3)
                displayObject->dest->x += data->speed;
            else
                displayObject->dest->y += data->speed;

            data->currentFrameIndex++;

            if (data->currentFrameIndex == 3)
            {
                data->currentFrameIndex = 0;
            }
        }
    }
}

DisplayObject *WalkAnimationCreate()
{
    WalkAnimationData *data = malloc(sizeof(WalkAnimationData));
    data->currentFrameIndex = 0;
    data->currentDir = 0;
    data->globalFramesCount = 0;
    data->_walking = SDL_FALSE;
    data->speed = 4;
    data->frameFlip = SDL_FLIP_NONE;
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            data->frames[i][j].y = i * 16 + 1 * i;
            data->frames[i][j].x = j * 16 + 1 * j;

            data->frames[i][j].w = 16;
            data->frames[i][j].h = 16;
        }
        data->frames[i][4].y = data->frames[i][0].y;
        data->frames[i][4].x = data->frames[i][0].x;
        data->frames[i][4].w = 16;
        data->frames[i][4].h = 16;
    }

    struct DisplayObject *obj = DisplayObjectCreate(0, 0, 16, 16, &WalkAnimationOnDraw, NULL);
    obj->subClassData = data;
    return obj;
}

void WalkAnimationGotoAndPlay(struct DisplayObject *anim, int frameIndex)
{
    WalkAnimationData *data = anim->subClassData;
    data->currentFrameIndex = frameIndex;
    data->_walking = SDL_TRUE;
}

SDL_bool WalkAnimationIsWalking(struct DisplayObject *anim)
{
    WalkAnimationData *data = anim->subClassData;
    return data->_walking;
}

void WalkAnimationGotoAndStop(DisplayObject *anim, int frameIndex)
{
    WalkAnimationData *data = anim->subClassData;
    data->_walking = SDL_FALSE;
    data->currentFrameIndex = frameIndex;
}
void walkAnimDir(struct DisplayObject *anim, int dir)
{
    if (!WalkAnimationIsWalking(anim))
    {
        WalkAnimationData *data = anim->subClassData;
        data->currentDir = dir;
        if (dir == 3 || dir == 1)
        {
            if (data->speed > 0)
            {
                data->speed *= -1;
            }
        }
        else
        {
            if (data->speed < 0)
            {
                data->speed *= -1;
            }
        }

        data->frameFlip = SDL_FLIP_NONE;
        WalkAnimationGotoAndPlay(anim, 0);
    }
}

void WalkAnimationWalkRight(struct DisplayObject *anim)
{
    if (!WalkAnimationIsWalking(anim))
    {
        WalkAnimationData *data = anim->subClassData;
        if (data->speed < 0)
        {
            data->speed *= -1;
        }
        data->frameFlip = SDL_FLIP_NONE;
        WalkAnimationGotoAndPlay(anim, 0);
    }
}
void WalkAnimationWalkLeft(struct DisplayObject *anim)
{
    if (!WalkAnimationIsWalking(anim))
    {
        WalkAnimationData *data = anim->subClassData;
        if (data->speed > 0)
        {
            data->speed *= -1;
        }
        data->frameFlip = SDL_FLIP_NONE;
        WalkAnimationGotoAndPlay(anim, 0);
    }
}

void WalAnimationStop(struct DisplayObject *anim)
{
    WalkAnimationGotoAndStop(anim, 4);
}

void WalkAnimationDestroy(struct DisplayObject *self)
{
    WalkAnimationData *data = self->subClassData;
    free(data);
    DisplayObjectDestroy(self);
}